]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
windowManager: Implement keybinding_filter hook
authorFlorian Müllner <fmuellner@gnome.org>
Mon, 20 Aug 2012 08:38:13 +0000 (10:38 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Sat, 17 Nov 2012 00:44:22 +0000 (01:44 +0100)
We are currently using a hack to allow a select set of keybindings
in the overview. Implement the new MetaPlugin keybinding_filter
hook, which provides a cleaner way to achieve the same.

https://bugzilla.gnome.org/show_bug.cgi?id=688202

js/ui/main.js
js/ui/windowManager.js
src/gnome-shell-plugin.c
src/shell-wm-private.h
src/shell-wm.c

index 638a8577724650024eea90819de4eae5647d5b1d..db7698bd34ac98e6def751d59aa890b632a3abfc 100644 (file)
@@ -167,8 +167,6 @@ function start() {
 
     _startDate = new Date();
 
-    global.stage.connect('captured-event', _globalKeyPressHandler);
-
     log('GNOME Shell started at ' + _startDate);
 
     let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
@@ -465,86 +463,6 @@ function getWindowActorsForWorkspace(workspaceIndex) {
     });
 }
 
-// This function encapsulates hacks to make certain global keybindings
-// work even when we are in one of our modes where global keybindings
-// are disabled with a global grab. (When there is a global grab, then
-// all key events will be delivered to the stage, so ::captured-event
-// on the stage can be used for global keybindings.)
-function _globalKeyPressHandler(actor, event) {
-    if (modalCount == 0)
-        return false;
-    if (event.type() != Clutter.EventType.KEY_PRESS && event.type() != Clutter.EventType.KEY_RELEASE)
-        return false;
-
-    if (!sessionMode.allowKeybindingsWhenModal) {
-        if (modalCount > (overview.visible ? 1 : 0))
-            return false;
-    }
-
-    let symbol = event.get_key_symbol();
-    let keyCode = event.get_key_code();
-    let ignoredModifiers = global.display.get_ignored_modifier_mask();
-    let modifierState = event.get_state() & ~ignoredModifiers;
-
-    // This relies on the fact that Clutter.ModifierType is the same as Gdk.ModifierType
-    let action = global.display.get_keybinding_action(keyCode, modifierState);
-
-    if (event.type() == Clutter.EventType.KEY_PRESS) {
-        if (action == Meta.KeyBindingAction.SWITCH_PANELS) {
-            ctrlAltTabManager.popup(modifierState & Clutter.ModifierType.SHIFT_MASK,
-                                    modifierState);
-            return true;
-        }
-
-        switch (action) {
-            // left/right would effectively act as synonyms for up/down if we enabled them;
-            // but that could be considered confusing; we also disable them in the main view.
-            //
-            // case Meta.KeyBindingAction.WORKSPACE_LEFT:
-            //  if (!sessionMode.hasWorkspaces)
-            //      return false;
-            //
-            //     wm.actionMoveWorkspaceLeft();
-            //     return true;
-            // case Meta.KeyBindingAction.WORKSPACE_RIGHT:
-            //  if (!sessionMode.hasWorkspaces)
-            //      return false;
-            //
-            //     wm.actionMoveWorkspaceRight();
-            //     return true;
-            case Meta.KeyBindingAction.WORKSPACE_UP:
-                if (!sessionMode.hasWorkspaces)
-                    return false;
-
-                wm.actionMoveWorkspace(Meta.MotionDirection.UP);
-                return true;
-            case Meta.KeyBindingAction.WORKSPACE_DOWN:
-                if (!sessionMode.hasWorkspaces)
-                    return false;
-
-                wm.actionMoveWorkspace(Meta.MotionDirection.DOWN);
-                return true;
-            case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
-            case Meta.KeyBindingAction.COMMAND_2:
-                if (!sessionMode.hasRunDialog)
-                    return false;
-
-                openRunDialog();
-                return true;
-            case Meta.KeyBindingAction.PANEL_MAIN_MENU:
-                overview.hide();
-                return true;
-        }
-    } else if (event.type() == Clutter.EventType.KEY_RELEASE) {
-        if (action == Meta.KeyBindingAction.OVERLAY_KEY) {
-            overview.hide();
-            return true;
-        }
-    }
-
-    return false;
-}
-
 function _findModal(actor) {
     for (let i = 0; i < modalActorFocusStack.length; i++) {
         if (modalActorFocusStack[i].actor == actor)
index 6a52037d72512843892137d42d744a68134ba0c0..eb7570f480dc7534a094067a3537276ea4d39910 100644 (file)
@@ -99,6 +99,7 @@ const WindowManager = new Lang.Class({
         this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
         this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
         this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
+        this._shellwm.connect('filter-keybinding', Lang.bind(this, this._filterKeybinding));
 
         this._workspaceSwitcherPopup = null;
         Meta.keybindings_set_custom_handler('switch-to-workspace-left',
@@ -424,6 +425,36 @@ const WindowManager = new Lang.Class({
         }
     },
 
+    _filterKeybinding: function(shellwm, binding) {
+        if (!Main.sessionMode.allowKeybindingsWhenModal) {
+            if (Main.modalCount > (Main.overview.visible ? 1 : 0))
+                return true;
+        }
+        let action = Meta.prefs_get_keybinding_action(binding.get_name());
+        switch (action) {
+            // left/right would effectively act as synonyms for up/down if we enabled them;
+            // but that could be considered confusing; we also disable them in the main view.
+            //
+            // case Meta.KeyBindingAction.WORKSPACE_LEFT:
+            // case Meta.KeyBindingAction.WORKSPACE_RIGHT:
+            case Meta.KeyBindingAction.WORKSPACE_UP:
+            case Meta.KeyBindingAction.WORKSPACE_DOWN:
+                return !Main.sessionMode.hasWorkspaces;
+
+            case Meta.KeyBindingAction.PANEL_RUN_DIALOG:
+            case Meta.KeyBindingAction.COMMAND_2:
+            case Meta.KeyBindingAction.PANEL_MAIN_MENU:
+            case Meta.KeyBindingAction.OVERLAY_KEY:
+            case Meta.KeyBindingAction.SWITCH_PANELS:
+                return false;
+        }
+
+        if (Main.modalCount == 0 && binding.is_builtin())
+            return false;
+
+        return true;
+    },
+
     _switchWorkspace : function(shellwm, from, to, direction) {
         if (!this._shouldAnimate()) {
             shellwm.completed_switch_workspace();
index 737c19067bafa14197bc036775912d8beda03d63..03ae79a39c0741ea148223d56318cbf70613e1ea 100644 (file)
@@ -72,6 +72,9 @@ static void gnome_shell_plugin_kill_switch_workspace (MetaPlugin      *plugin);
 
 static gboolean              gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
                                                                XEvent     *event);
+
+static gboolean              gnome_shell_plugin_keybinding_filter (MetaPlugin *plugin,
+                                                                   MetaKeyBinding *binding);
 static const MetaPluginInfo *gnome_shell_plugin_plugin_info   (MetaPlugin *plugin);
 
 
@@ -126,8 +129,9 @@ gnome_shell_plugin_class_init (GnomeShellPluginClass *klass)
   plugin_class->kill_window_effects   = gnome_shell_plugin_kill_window_effects;
   plugin_class->kill_switch_workspace = gnome_shell_plugin_kill_switch_workspace;
 
-  plugin_class->xevent_filter    = gnome_shell_plugin_xevent_filter;
-  plugin_class->plugin_info      = gnome_shell_plugin_plugin_info;
+  plugin_class->xevent_filter     = gnome_shell_plugin_xevent_filter;
+  plugin_class->keybinding_filter = gnome_shell_plugin_keybinding_filter;
+  plugin_class->plugin_info       = gnome_shell_plugin_plugin_info;
 }
 
 static void
@@ -337,6 +341,13 @@ gnome_shell_plugin_xevent_filter (MetaPlugin *plugin,
   return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
 }
 
+static gboolean
+gnome_shell_plugin_keybinding_filter (MetaPlugin     *plugin,
+                                      MetaKeyBinding *binding)
+{
+  return _shell_wm_filter_keybinding (get_shell_wm (), binding);
+}
+
 static const
 MetaPluginInfo *gnome_shell_plugin_plugin_info (MetaPlugin *plugin)
 {
index c0cd84d23b183f851b3d0c1f5cc6140b207e0add..6fc9348cebdb9add6e74cb8b366d1b53d8442b80 100644 (file)
@@ -35,6 +35,9 @@ void _shell_wm_kill_window_effects   (ShellWM             *wm,
                                       MetaWindowActor     *actor);
 void _shell_wm_kill_switch_workspace (ShellWM             *wm);
 
+gboolean _shell_wm_filter_keybinding (ShellWM             *wm,
+                                      MetaKeyBinding      *binding);
+
 G_END_DECLS
 
 #endif /* __SHELL_WM_PRIVATE_H__ */
index 835c970cd84e632ebe115de89225bb6710c4500f..08aceb7f20cefc2d93c1035a45d1a3e127008baa 100644 (file)
@@ -26,6 +26,7 @@ enum
   SWITCH_WORKSPACE,
   KILL_SWITCH_WORKSPACE,
   KILL_WINDOW_EFFECTS,
+  FILTER_KEYBINDING,
 
   LAST_SIGNAL
 };
@@ -115,6 +116,14 @@ shell_wm_class_init (ShellWMClass *klass)
           NULL, NULL, NULL,
                  G_TYPE_NONE, 1,
                  META_TYPE_WINDOW_ACTOR);
+  shell_wm_signals[FILTER_KEYBINDING] =
+    g_signal_new ("filter-keybinding",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  g_signal_accumulator_true_handled, NULL, NULL,
+                  G_TYPE_BOOLEAN, 1,
+                  META_TYPE_KEY_BINDING);
 }
 
 void
@@ -267,6 +276,17 @@ _shell_wm_destroy (ShellWM         *wm,
   g_signal_emit (wm, shell_wm_signals[DESTROY], 0, actor);
 }
 
+gboolean
+_shell_wm_filter_keybinding (ShellWM             *wm,
+                             MetaKeyBinding      *binding)
+{
+  gboolean rv;
+
+  g_signal_emit (wm, shell_wm_signals[FILTER_KEYBINDING], 0, binding, &rv);
+
+  return rv;
+}
+
 /**
  * shell_wm_new:
  * @plugin: the #MetaPlugin